package com.yanxu.stopthreads.producerandconsumer;

import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @author 折戟沉沙铁未销
 * @version V1.0
 *  使用 Volatile 修饰Boolean 类型的标志位 控制线程的停止。
 *  使用这种方式在有些情况下是可以的，但是有些情况是不可以的。
 *  所以，使用这种方式并不是一个通用的解决方案。
 *
 *  下面演示可以用的情况
 */
public class VolatileBooleanStop_NotCanUse {

    //定义一个标志位，并使用 [volatile] 进行修饰
    public static volatile Boolean stopFlag = false;

    //定义一个 BlockingQueue 阻塞队列
    public static BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10);

    public static void main(String[] args) throws InterruptedException {
        //启动生产者
        Thread thread = new Thread(new Producer(blockingQueue, stopFlag));
        thread.start();

        Thread.sleep(500);
        //消费者消费（main 主线程进行消费）
        Consumer consumer=new Consumer(blockingQueue);
        while (consumer.isNeedConsume()){
            Integer take = blockingQueue.take();
            System.out.println("消费者消费了一个" + take);
            Thread.sleep(500);
        }
        System.out.println("消费者不在继续消费了!!!");
        stopFlag = true;
    }
}

/***** 生产者 *****/
class Producer implements Runnable{
    private BlockingQueue<Integer> blockingQueue;
    private Boolean flag;

    public Producer(BlockingQueue<Integer> blockingQueue,Boolean flag) {
        this.blockingQueue = blockingQueue;
        this.flag = flag;
    }

    public void run() {
        int num = 0;
        try {
            while (true && !flag){
                blockingQueue.put(++num);
                System.out.println("生产者生产了一个!!!"+num);
                Thread.sleep(50);
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            System.out.println("生产者逻辑执行完毕，生产线程结束!!!");
        }
    }
}

/***** 消费者 *****/
class Consumer {
    private BlockingQueue<Integer> blockingQueue;

    public Consumer(BlockingQueue<Integer> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    public boolean isNeedConsume() {
        Random random = new Random();
        int randomInt = random.nextInt(100);
        System.err.println("random"+randomInt);
        if (randomInt < 90) {
            return true;
        }
        return false;
    }
}